لما لا نضع كل بيانات المشروع بداخل جدول واحد؟
في البداية و قبل الخوض في موضوع ربط معلومات الجداول, يجب أن تعرف لما نقوم بتوزيع بيانات المشروع على عدة جداول بدل وضعها كلها في جدول واحد.
في حال كنت ستضع كل بيانات المشروع في جدول واحد, ستواجه المشاكل التالية:
ستضطر إلى تكرار الكثير من القيم في كل سطر تضيفه.
الحقول التي لا تنوي وضع قيم فيها ستكون قيمتها
NULLو بالتالي أيضاً ستجد الحقول الفارغة تتكرر في كل سطر تضيفه.قد تحتاج إلى مئات الأعمدة حتى تتمكن من تخزين كل المعلومات.
تكرار نفس المعلومات أكثر من مرة في قاعدة البيانات يتطلب مساحة كبيرة للتخزين.
إيجاد المعلومات و إجراء عمليات عليها سيستغرق وقت أكثر كلما أصبح حجم قاعدة البيانات أكبر.
مثال
إذا كنت ستقوم بتخزين معلومات الزبائن و طلبياتهم في جدول واحد فقط كالتالي.
لاحظ كم سيكون هناك حقول فارغة و قيم متكررة لأنك ستضطر إلى أعادة إدخال نفس معلومات الزبون بجانب طلبيته.
| person_id | first_name | last_name | order_number | product_1_name | product_1_price | product_2_name | product_2_price | product_3_name | product_3_price |
|---|---|---|---|---|---|---|---|---|---|
| 1 | Ahmad | Alhazem | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 1 | Ahmad | Alhazem | 100 | Computer Screen | 160 | NULL | NULL | NULL | NULL |
| 1 | Ahmad | Alhazem | 215 | Keyboard | 10 | Mouse | 7 | NULL | NULL |
إذا اطلعت جيداً على الجدول ستلاحظ أن كل فاتورة أجراها الزبون تطلبت إعادة إدخال معلوماته (إسمه, إسمه و عائلته) من جديد.
المشكلة الثانية التي تظهر هي أنه يوجد حقول كثيرة فارغة في كل سطر.
المشاكل التي تكلمنا عنها لا تقتصر على التكرار فقط, فمثلاً في حال أردنا تحديث إسم الزبون, سنضطر إلى تحديث إسمه في كل سطر خاص به و ليس مرة واحدة.
خلاصة
لا تفكر إطلاقاً بوضع كل بيانات المشروع بداخل جدول واحد, بل فكر دائماً بأن عليك توزيع بيانات المشروع على عدة جداول بشكل منطقي و مرتب.
كيف يتم ربط الجداول مع بعضها؟
في البداية عليك معرفة أن ربط الجداول مع بعضها هو شيء نحققه من خلال بناء الجداول بشكل مترابط منطقياً.
بمعنى أنك لا تقوم بكتابة أمر خاص حتى تربط قيم الجداول مع بعضها.
ما نفعله حتى نربط البيانات الموضوعة في أي جدول مع البيانات الموضوعة في جدول آخر, هو وضع عامود خاص في كل جدول تكون جميع قيمه موحدة (أي لا يوجد فيها أي تكرار) مثل العامود id الذي كنا نضعه في كل جدول ننشئه تماماً كما في المثال التالي.
مثال
في حال كانت قاعدة البيانات تحتوي على جدولين كالتالي:
الجدول الأول إسمه
countriesو هو مخصص لحفظ معلومات البلدان.الجدول الثاني إسمه
usersو هو مخصص لحفظ معلومات المستخدمين و التي من ضمنها بلد كل مستخدم.
إذا إفترضنا أن الجدول countries يتضمن معلومات 3 بلدان فقط كالتالي.
| countries | ||
|---|---|---|
| id | name | currency |
| 1 | Lebanon | Lebanese Pound |
| 2 | Oman | Omani Riyal |
| 3 | Egypt | Egyption Pound |
و إذا إفترضنا أن الجدول users يتضمن معلومات 5 مستخدمين كالتالي.
و هنا لاحظ أننا لم نكتب أسماء بلدان المستخدمين من جديد, بل وضعنا فقط رقم تعرفة البلد المذكور في الجدول countries.
| users | |||
|---|---|---|---|
| id | first_name | last_name | country_id |
| 1 | Ahmad | Eid | 1 |
| 2 | Ramez | Morad | 3 |
| 3 | Hassan | Mortada | 2 |
| 4 | Saad | Alkassem | 1 |
| 5 | Zaher | Fahmi | 3 |
الآن, إذا وضعنا الجدولين بجانب بعض, سنلاحظ كيف ربطنا قيم الجدول users بقيم الجدول countries من خلال رقم التعرفة id الخاص بكل بلد.
إذا نظرنا أولاً إلى الجدول countries سنجد أن كل سطر فيه يملك رقم id خاص.
إذا نظرنا بعدها إلى الجدول users سنجد أن العامود country_id يستخدم قيم العامود id الموجودة في الجدول countries للإشارة إلى بلدان المستخدمين.
معلومات الجدول countries نقرؤها كالتالي:
البلد رقم
1هو السعوديةKSAو عملته الربال السعوديSaudi Riyal.البلد رقم
2هو عمانOmanو عملته الربال السعوديOmani Riyal.البلد رقم
3هو مصرEgyptو عملته الجنيه المصريEgyption Pound.
إذاً أصبحنا قادرين على معرفة البلد من خلال رقم التعرفة id الخاص به.
معلومات الجدول users يمكننا قراءتها كالتالي:
المستخدم رقم
1إسمهAhmad Eid, و هو من السعوديةKSAلأنه من البلد رقم1.المستخدم رقم
2إسمهRamez Morad, و هو من عمانOmanلأنه من البلد رقم2.المستخدم رقم
3إسمهHassan Mortada, و هو من مصرEgyptلأنه من البلد رقم3.المستخدم رقم
4إسمهSaad Alkassem, و هو من السعوديةKSAلأنه من البلد رقم1.المستخدم رقم
5إسمهZaher Fahmi, و هو من مصرEgyptلأنه من البلد رقم3.
فوائد ربط الجداول مع بعضها
1- التخلص من القيم المكررة
بكل بساطة إذا نظرت للجدولين users و countries ستلاحظ أنهما لا يحتويان على أي حقول فارغة لا داعي لها, و لا يوجد قيم مكررة.
2- تحديث القيمة مرة واحدة لجميع
إذا قمت بتحديث أي معلومة عادية في الجدول countries, فإنها ستتغير بشكل تلقائي بالنسبة كل جدول مرتبط به.
أي إذا قمنا بتحديث قيمة الحقل name و الحقل currency في الجدول countries فإنها ستتحدث بشكل تلقائي بالنسبة لكل مستخدم مرتبط بها في الجدول users حيث أن جميع المستخدمين في هذا الجدول مرتبطين برقم id البلد الثابت في الجدول countries و ليس بقيمه بشكل مباشر.
3- إضافة معلومات جديدة مرة واحدة للجميع
إذا قمت بإضافة عامود جديد في الجدول countries سيتم إضافته أيضاً بالنسبة لجميع المستخدمين في الجدول users.
فمثلاً, في حال قمنا بإضافة عامود جديد في الجدول countries إسمه symbol وضعنا فيه رمز عملة كل بلد كالتالي.
عندها, بدون إجراء أي تعديل على الجدول users سنعرف رمز العملة التي يعرفها كل مستخدم من خلال رقم تعرفة البلد country_id الموضوع مسبقاً.
فعلى سبيل المثال, أي مستخدم يملك country_id يساوي 1 يعرف العملة التي يرمز لها بالحرفين LBP.
4- الدقة في حفظ المعلومات
ما سنتكلم عنه الآن, سنشرحه بتفصيل ممل لاحقاً و لكن خذ فكرة عامة عنه.
إذا تم تعيين العامود country_id كمفتاح أجنبي ( Foreign Key ) بالنسبة للعامود id الموجود في الجدول countries, عندها يصبج العامود country_id قادر على تخزين أرقام من العامود id الموجود في الجدول countries فقط.
في حالتنا, يصبح العامود country_id قادر على أن يخزن الأرقام 1 و 2 و 3 فقط.
بمعنى آخر, إذا حاولت تخزين الرقم 100 في الحقل country_id سيتم منعك من ذلك لأن الحقل id الموجود في الجدول countries لا يوجد فيه القيمة 100.
طريقة ربط القيم الموضوعة في عدة جداول عند استرجاعها
عند حفظ البيانات, شاهدنا كيف أننا نحفظها في عدة جداول بشكل منطقي و مرتب و خالي من أي تكرار.
السؤال الأهم الآن, إذا تم وضع البيانات في عدة جداول, و عند الحاجة لاسترجاعها نريد تجميعها في جدول واحد فقط كيف نفعل ذلك؟
ببساطة, عند جلب البيانات بواسطة الأمر SELECT نقوم بوضع أسماء الجداول التي سنحضر منها القيم و نذكر أسماء الأعمدة التي تربط الجداول باستخدام الكلمة ON فتقوم قاعدة البيانات بتجميع القيم الموجودة في أكثر من جدول و ترجعها كجدول واحد.
كمثال بسيط, يمكنك دمج الجدولين users و countries في جدول واحد عند جلبها كالتالي.
| id | first_name | last_name | country |
|---|---|---|---|
| 1 | Ahmad | Eid | Lebanon |
| 2 | Ramez | Morad | Egypt |
| 3 | Hassan | Mortada | Oman |
| 4 | Saad | Alkassem | Lebanon |
| 5 | Zaher | Fahmi | Egypt |
في الدرس التالي ستفهم أنواع العلاقات بين الجدوال حتى تفهم طريقة بناء الجداول بشكل مترابط.
من بعدها ستتعلم طريقة ربط القيم المشتركة و الموزعة على عدة جداول عند استرجاعها بتفصيل ممل أيضاً.
مفهوم العلاقات في قواعد البيانات
في البداية, قبل بناء أي قاعدة بيانات يجب ان يكون لديك معرفة دقيقة بالمعلومات التي ينوي صاحب المشروع أن يتم تخزينها.
على أساس المعلومات التي ينوي صاحب العمل تخزينها في المشروع, تقوم ببناء قاعدة البيانات حتى تخزنها بما يلائم المشروع.
الآن, بعد معرفة كل المعلومات التي ينوي صاحب المشروع تخزينها, سيكون عليك إنشاء عدة جداول في قاعدة البيانات بهدف تخزين المعلومات التي يتم إدخالها بشكل صحيح خالي من أي تكرار.
عندما يحاول المبرمج المبتدئ إنشاء الجداول في قاعدة البيانات, فإنه في العادة يضيع في نقطة واحدة و هي كيفية توزيع بيانات المشروع على عدة جداول بشكل صحيح حتى يستطيع ربطها مع بعضها من جديد عندما يريد إسترجاعها و هذا ما ستتعلمه بالضبط من هذا الدرس.
بشكل عام, بمجرد أن تفهم نوع العلاقة المنطقية بين معلومات المشروع, تأكد أنك قادر على بناء أي قاعدة بيانات تريد حتى و إن كانت تتألف من ألف جدول.
أنواع العلاقات بين الجداول
عند التفكير بنوع العلاقة بين جدول و آخر, فإنه سيكون أحد الإحتمالات التالية:
واحد لواحد ( One to One ).
واحد لمتعدد ( One to Many ).
متعدد لمتعدد ( Many to Many ).
إعداد رسومات لتوضيح نوع العلاقة بين الجداول
عند إعداد رسم لإيضاح نوع العلاقة بين الجداول, قد تجد إختلاف في طرق الرسم على حسب البرنامج الذي تستخدمه و لكن الفكرة ستكون نفسها تماماً.
بالإضافة إلى ذلك, قد تجد الرسم يضع أسماء الجداول فقط أثناء رسم العلاقات فيما بينها.
و قد تجد البرنامج أكثر دقة حيث يريك كيف أن الأعمدة بداخل الجداول مرتبطة مع بعضها البعض.
علاقة واحد لواحد ( One to One )
هذه العلاقة تعني أن كل قيمة في الجدول, لا يمكن أن يستخدهها الجدول الآخر أكثر من مرة واحدة.
كمثال بسيط, أثناء تسجيل المواطنين في سجلات الدولة الرسمية, تقوم السلطات المختصة بإعطاء كل مواطن رقم فريد يميزه عن بقية المواطنين حتى تتجنب الوقوع بخطأ تشابه الأسماء عند إجراء أي معاملة قانونية متعلقة به. هذا الرقم يسمى الرقم الوطني للشخص.
الرقم الوطني قد يستخدم في أمكان عديدة و لكن في بعض الحالات قد يكون إستخدامه ممكناً مرة واحدة و إليك بعض الأمثلة.
المثال الأول
كل مواطن يعمل في وظيفة ما يتم إعطاؤه رقم ضريبي خاص به في الدولة, هذا الرقم يتم وضعه في الأساس بناءاً على الرقم الوطني للمواطن.
من المنطقي جداً في هذه الحالة أن يكون كل شخص يملك رقم ضريبي واحد لأن هذا الرقم ستستخدمه الدولة لتحدد الضرائب المترتبة على كل مواطن من خلاله.
المثال الثاني
يمكن للمواطن يمكنه الحصول على رخصة قيادة واحدة من نفس النوع, فمثلاً لا يمكن للمواطن إمتلاك رخصتين لقيادة السيارات في وقت واحد.
رقم رخصة القيادة التي تعطى للمواطن يتم وضعه في الأساس بناءاً على الرقم الوطني للمواطن لأنه الشيء الوحيد الذي يضمن تمييزه عن باقي المواطنين.
المثال الثالث
إذا قدمت طلب للحصول على جواز سفر, سيتم تسجيل أن المواطن رقم كذا أصبح يملك جواز السفر رقم كذا. و في حال فقدت جواز سفرك أو أردت الحصول على جواز سفر جديد, تجدهم يقوموا بإتلاف جواز سفرك القديم و يعطوك جواز سفر جديد بدلاً منه. أي تجدهم يسمحوا لك باقتناء جواز سفر واحد باسمك.
إذاً, في حالة جواز السفر فإنه يسمح بأن يتم تسجيل جواز سفر واحد لكل شخص أيضاً.
رقم جواز السفر الذي يعطى للمواطن يتم وضعه في الأساس بناءاً على الرقم الوطني للمواطن لأنه الشيء الوحيد الذي يضمن تمييزه عن باقي المواطنين.
طريقة رسم العلاقة واحد لواحد
شكل الرموز المستخدمة في تحديد شكل علاقة واحد لواحد بين جدول و آخر يختلف من برنامج لآخر و لكن الفكرة هي نفسها.
قد تجد خط بين الجدولين عليه 1 : 1 كالتالي.
قد تجد خط بين الجدولين في كل طرف منه يوجد 1 كالتالي.
قد تجد خط بين الجدولين في كل طرف منه يوجد خط واحد عامودي كالتالي.
في حال كانت العلاقة محددة بدقة بين الجداول, سيتم وصل الخط الذي يربط الأعمدة المشتركة بين الجداول مباشرةً عليها, و هنا يمكننا وضع أي رمز من الرموز السابقة للإشارة إلى أن العلاقة بينهما هي واحد لواحد كالتالي.
طريقة حفظ البيانات في علاقة واحد لواحد
الصورة التالية توضح كيف تكون البيانات مخزنة في الجداول في حال كان نوع العلاقة واحد لواحد.
لاحظ أنه في الجدول passports لا يمكن وجود رقم id أي شخص أكثر من مرة لأنه بالمنطق لا يمكن السماح للشخص بالحصول على أكثر من جواز سفر.
علاقة واحد لمتعدد ( One to Many )
هذه العلاقة تعني أنه كل قيمة في الجدول, يمكن أن يستخدهها الجدول الآخر بالقدر الذي يريده.
هذه العلاقة هي أكثر نوع من العلاقات التي نتعامل معها و إليك بعض الأمثلة:
في موقع فيسبوك, يستطيع المستخدم أن ينشر عدد غير محدد من البوستات و التعليقات.
في موقع تويتر, يستطيع المستخدم أن ينشر عدد غير محدد من التغريدات و التعليقات.
في موقع يوتيوب, يستطيع صاحب القناة أن ينشر عدد غير محدد من الفيديوهات, و يستطيع أن يعلق عليها هو و متابعيه قدر ما شاء إلخ..
طريقة رسم العلاقة واحد لمتعدد
شكل الرموز المستخدمة في تحديد شكل علاقة واحد لمتعدد بين جدول و آخر يختلف من برنامج لآخر و لكن الفكرة هي نفسها.
قد تجد خط بين الجدولين عليه 1 : M كالتالي.
قد تجد خط بين الجدولين في طرف منه يوجد 1 و في طرف آخر يوجد M كالتالي.
قد تجد خط بين الجدولين في طرف منه يوجد 1 و في طرف آخر يوجد % كالتالي.
قد تجد خط بين الجدولين في طرف منه يوجد خط واحد عامودي و في طرف آخر يوجد ثلاث خطوط مرتبطة كالتالي.
في حال كانت العلاقة محددة بدقة بين الجداول, سيتم وصل الخط الذي يربط الأعمدة المشتركة بين الجداول مباشرةً عليها, و هنا يمكننا وضع أي رمز من الرموز السابقة للإشارة إلى أن العلاقة بينهما هي واحد لمتعدد كالتالي.
طريقة حفظ البيانات في علاقة واحد لمتعدد
الصورة التالية توضح كيف تكون البيانات مخزنة في الجداول في حال كان نوع العلاقة واحد لمتعدد.
لاحظ أنه في الجدول posts يمكن وجود رقم user_id أي شخص أكثر من مرة لأنه بالمنطق يمكن للشخص كتابة أكثر من منشور أو مقال.
علاقة متعدد لمتعدد ( Many to Many )
هذه العلاقة تعني أن كل قيمة في الجدول, يمكن أن يستخدهها الجدول الآخر بالقدر الذي يريده و العكس صحيح.
هذا النوع من العلاقات قد يمر معك في بعض الأحيان و هو النوع الوحيد من العلاقات الذي يحتاج طريقة خاصة للتعامل معه.
كمثال بسيط, في حال كنت تبني قاعدة بيانات لجامعة, و تريد تخزين معلومات الطلاب و المواد المسجل بها كل طالب.
هنا الطالب يمكنه أن يتسجل في عدة مواد في نفس الوقت, و المادة الواحدة يمكن أن يتسجل بها عدة طلاب في نفس الوقت أيضاً.
إذاً طبيعة العلاقة بين جدول الطلاب و جدول المواد هي علاقة متعددة.
طريقة رسم العلاقة متعدد لمتعدد
شكل الرموز المستخدمة في تحديد شكل علاقة متعدد لمتعدد بين جدول و آخر يختلف من برنامج لآخر و لكن الفكرة هي نفسها.
قد تجد خط بين الجدولين عليه M : M كالتالي.
قد تجد خط بين الجدولين في كل طرف منه يوجد M كالتالي.
قد تجد خط بين الجدولين في كل طرف منه يوجد % كالتالي.
قد تجد خط بين الجدولين في كل طرف منه يوجد ثلاث خطوط مرتبطة كالتالي.
طريقة إنشاء علاقة متعدد لمتعدد
في مثالنا السابق حول الطلاب و المواد, لا بد لنا أن نضع معلومات الطلاب في جدول و معلومات المواد في جدول آخر.
بعدها يجب أن نفكر بطريقة لربط هذين الجدولين مع بعضهما حتى نستطيع معرفة مواد كل طالب أو من هم طلاب كل مادة.
قاعدة عامة: لربط أي جدولين بشكل تكون العلاقة بينهما متعدد لمتعدد, يجب أن تنشئ جدول ثالث حتى يكون وسيط بينهما.
إذاً في العلاقة التي نوعها متعدد لمتعدد, لا يمكنك ربط معلومات الجدولين مع بعضهما إلا بإضافة جدول ثالث يكون بمثابة وسيط بينهما.
الآن, بما أن كل طالب في جدول الطلاب يملك رقم id خاص به و كل مادة في جدول المواد تملك رقم id خاص بها أيضاً, سنعتمد على هذه الأرقام في الجدول الوسيط من أجل تحديد كل طالب في أي مادة مسجل لأنها الشيء الوحيد الذي نستطيع من خلاله تمييز الطلاب عن بعضهم و تمييز المواد عن بعضها.
عند إضافة جدول وسيط بين الجدولين سيصبح شكل الرسم كالتالي.
لاحظ أننا قمنا بتحويل العلاقة M : M بين الجدولين students و methods إلى علاقتين نوعهما 1 : M عند ربطهما بالجدول الوسيط الذي قمنا بتسميته students_methods و ستفهم السبب بعد قليل.
في حال كانت العلاقة محددة بدقة بين الجداول, سيتم وصل الخط الذي يربط الأعمدة المشتركة بين الجداول مباشرةً عليها, و هنا يمكننا وضع أي رمز من الرموز السابقة للإشارة إلى أن العلاقة بينهما هي واحد لمتعدد كالتالي.
طريقة حفظ البيانات في علاقة متعدد لمتعدد
الصورة التالية توضح كيف تكون البيانات مخزنة في الجداول في حال كان نوع العلاقة متعدد لمتعدد.
لاحظ كيف أصبحنا قادرين على جعل الطالب قادر أن يتسجل في عدة مواد في نفس الوقت, و المادة الواحدة يمكن أن يتسجل بها عدة طلاب في نفس الوقت أيضاً.
إذا كنا سنقرأ المعلومات المخزنة في الجدول students_methods, يمكننا قرائتها إما بالنسبة لكل طالب و إما بالنسبة لكل مادة.
و لنقرأ المعلومات بشكل مفهوم, نقوم بتبديل id الطالب بإسم الطالب. و نقوم بتبديل id المادة بإسم المادة كما سنفعل الآن.
قراءة الجدول بالنسبة لكل طالب
الطالب أحمد مصري مسجل في المادة
Algorithmsو المادةNetwork 1.الطالب وسام العلي مسجل في المادة
Algorithmsو المادةWeb Development.
قراءة الجدول بالنسبة لكل مادة
المادة
Algorithmsمسجل فيها الطالب أحمد المصري و الطالب وسام العلي.المادة
Network 1مسجل فيها الطالب أحمد المصري.المادة
Web Developmentمسجل فيها الطالب وسام العلي.